package com.cal.utms.model.dealing;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import com.cal.utms.dao.dealing.InstrumentDao;
import com.cal.utms.dao.maintenance.IssuerDaoImpl;
import com.cal.utms.dto.dealing.InstrumentDto;
import com.cal.utms.dto.dealing.PurchaseDealDto;
import com.cal.utms.entity.Instrument;
import com.cal.utms.entity.InstrumentCouponDate;
import com.cal.utms.entity.InstrumentFloatingRate;
import com.cal.utms.entity.InstrumentType;
import com.cal.utms.entity.Issuer;
import com.cal.utms.enumType.InterestRate;

public class InstrumentModel {

	public Instrument createPurchaseDtoToInstrument(PurchaseDealDto dealDto, InstrumentType insType) {
		Instrument instrument = null;
		if (insType.getListed() == 0) {
			instrument = new Instrument();
		} else {
			InstrumentDao insDao = new InstrumentDao();
			instrument = insDao.getByCode(dealDto.getListedInsCode());
			if (instrument == null) {
				dealDto.setSuccess(false);
				dealDto.setStatus("Cannot Find Listed Instrument!");
				return instrument;
			}
		}

		return mapPurchaseDtoToInstrument(dealDto, insType, instrument);
	}

	public Instrument updatePurchaseDtoToInstrument(PurchaseDealDto dealDto, InstrumentType insType, Instrument instrument) {

		return mapPurchaseDtoToInstrument(dealDto, insType, instrument);

	}

	public Instrument confirmPurchaseDtoToInstrument(PurchaseDealDto dealDto, InstrumentType insType) {
		Instrument instrument = null;
		InstrumentDao insDao = new InstrumentDao();
		instrument = insDao.getByCode(dealDto.getListedInsCode());
		if (instrument == null) {
			dealDto.setSuccess(false);
			dealDto.setStatus("Cannot Find Listed Instrument!");
			return instrument;
		}
		instrument.setStatus("Not Received From Customer");
		return mapPurchaseDtoToInstrument(dealDto, insType, instrument);
	}

	public Instrument mapPurchaseDtoToInstrument(PurchaseDealDto dealDto, InstrumentType insType, Instrument instrument) {
		Number number;
		NumberFormat format = NumberFormat.getInstance();
		DateFormat df = new SimpleDateFormat("MM/dd/yyyy", Locale.ENGLISH);
		Date date = null;
		if (!(insType.getCouponAvailability() == 0)) {
			instrument.setCouponRate(new BigDecimal(dealDto.getCouponRate().replace("%", "")));
			if (insType.getCouponAvailability() == 1) {
				instrument.setCouponFreq(insType.getCuponFrequency());
			} else if (insType.getCouponAvailability() == 2) {
				List<InstrumentCouponDate> icdList = new ArrayList<InstrumentCouponDate>();
				InstrumentCouponDate icd = null;
				if (dealDto.getCouponDates() != null && !dealDto.getCouponDates().equals("")) {
					for (String cpnDate : dealDto.getCouponDates().split(";")) {
						try {
							date = df.parse(cpnDate);
							icd = new InstrumentCouponDate();
							icd.setInstrument(instrument);
							icd.setCouponDate(date);
							icdList.add(icd);
						} catch (ParseException e) {
							System.out.println("Invalid Coupon date:" + cpnDate + " for deal:" + dealDto.getName());
							e.printStackTrace();
						}
					}
					if (icdList.size() == 0) {
						dealDto.setSuccess(false);
						dealDto.setStatus("1: Cannot find Coupon Dates!");
						return instrument;
					} else {
						instrument.setInstrumentCouponDates(icdList);
					}
				} else {
					dealDto.setSuccess(false);
					dealDto.setStatus("2: Cannot find Coupon Dates!2");
					return instrument;
				}
			}
		}
		if (dealDto.getDayBasis() != null) {
			instrument.setDayBasis(dealDto.getDayBasis());
		} else if (insType.getDayBasis() != null) {
			instrument.setDayBasis(insType.getDayBasis());
		} else {
			dealDto.setSuccess(false);
			dealDto.setStatus("Day Basis not found!");
			return instrument;
		}

		try {
			if (insType.getCalculationInput() == 1) {
				number = format.parse(dealDto.getDealValue());
			} else {
				number = format.parse(dealDto.getMaturityValue());
			}
			System.out.println("Number: " + number);
			System.out.println("InsVal: " + instrument.getInstrumentValue());
			if (instrument.getInstrumentValue() == null) {
				instrument.setInstrumentValue(new BigDecimal(number.doubleValue()));
			} else {
				instrument.setInstrumentValue(instrument.getInstrumentValue().add(new BigDecimal(number.doubleValue())));
			}
		} catch (ParseException e) {
			System.out.println("Error in parsing Deal Value:" + dealDto.getDealValue());
			dealDto.setSuccess(false);
			dealDto.setStatus("Invalid Deal Value!");
			return instrument;
		}

		if (insType.getListed() != 0) {
			instrument.setInstrumentCode(dealDto.getListedInsCode());
		} else {
			IssuerDaoImpl issuerDao = new IssuerDaoImpl();
			Issuer issuer = null;

			instrument.setInstrumentCode(dealDto.getInsCode());
			instrument.setInstrumentType(insType);
			try {
				date = df.parse(dealDto.getValueDate());
				instrument.setIssueDate(date);
			} catch (ParseException e) {
				System.out.println("Invalid Value date:" + dealDto.getValueDate());
				dealDto.setSuccess(false);
				dealDto.setStatus("Invalid Value Date!");
				e.printStackTrace();
				return instrument;
			}
			try {
				date = df.parse(dealDto.getMaturityDate());
				instrument.setMaturityDate(date);
			} catch (ParseException e) {
				System.out.println("Invalid Maturity date:" + dealDto.getMaturityDate());
				dealDto.setSuccess(false);
				dealDto.setStatus("Invalid Maturity Date!");
				e.printStackTrace();
				return instrument;
			}

			if (dealDto.getPrimaryDealer() > 0) {
				issuer = issuerDao.getById(dealDto.getPrimaryDealer());
			} else if (dealDto.getIssuer() > 0) {
				issuer = issuerDao.getById(dealDto.getIssuer());
			} else {
				dealDto.setSuccess(false);
				dealDto.setStatus("Invalid Issuer!");
				return instrument;
			}
			if (issuer == null) {
				System.out.println("Invalid Issuer ID:" + dealDto.getIssuer());
			} else {
				instrument.setIssuer(issuer);
			}
		}

		if (insType.getInterestRate() == InterestRate.V) {
			if (dealDto.getBenchMark() != null && !dealDto.getBenchMark().equals("")) {
				instrument.setBenchMark(dealDto.getBenchMark());
			}
			instrument.setCeiling(new BigDecimal(dealDto.getCeilingValue()));
			instrument.setFloor(new BigDecimal(dealDto.getFloorValue()));

			if (dealDto.getResetDate() != null && !dealDto.getResetDate().equals("")) {
				try {
					date = df.parse(dealDto.getResetDate());
					instrument.setResetDate(date);
				} catch (ParseException e) {
					System.out.println("Invalid Reset date:" + dealDto.getResetDate());
					dealDto.setSuccess(false);
					dealDto.setStatus("Invalid Reset Date!");
					e.printStackTrace();
					return instrument;
				}
			} else {
				dealDto.setSuccess(false);
				dealDto.setStatus("Missing Reset Date!");
				return instrument;
			}

			if (dealDto.getRateResetPeriod() == 0) {
				dealDto.setSuccess(false);
				dealDto.setStatus("Missing Reset Period!");
				return instrument;
			} else {
				instrument.setResetPeriod(dealDto.getRateResetPeriod());
			}
			List<InstrumentFloatingRate> instrumentFloatingRates = new ArrayList<InstrumentFloatingRate>();
			instrument.setInstrumentFloatingRates(instrumentFloatingRates);
			InstrumentFloatingRate ifr = new InstrumentFloatingRate();
			ifr.setInstrument(instrument);
			ifr.setStartingDate(instrument.getIssueDate());
			ifr.setNextReset(instrument.getResetDate());
			ifr.setRate(new BigDecimal(dealDto.getRateinterest()));
			instrumentFloatingRates.add(ifr);
		}

		if (insType.getDenominals() != 0) {
			instrument.setMinDenominal(new BigDecimal(dealDto.getDenominalMinVal()));
		}
		// if(insType.getInterestRate()==InterestRate.V){}
		/*
		 * if(dealDto.getResetDate()!=null &&
		 * !dealDto.getResetDate().equals("")) try { date =
		 * df.parse(dealDto.getResetDate()); instrument.setResetDate(date); }
		 * catch (ParseException e) {
		 * System.out.println("Invalid Reset date:"+dealDto.getResetDate());
		 * dealDto.setSuccess(false); dealDto.setStatus("Invalid Reset Date!");
		 * e.printStackTrace(); return instrument; }
		 */
		return instrument;
	}

	public InstrumentDto getInstrumentById(int instrumentId) {
		System.out.println("###" + instrumentId);
		NumberFormat nf = new DecimalFormat("###,###.00");
		DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
		InstrumentDao dao = new InstrumentDao();
		Instrument instrument = dao.getById(instrumentId);
		InstrumentDto dto = new InstrumentDto();
		if (instrument != null) {
			if (instrument.getInstrumentType().getCouponAvailability() == 0) {
				dto.setCouponRate("0.00%");
			} else {
				dto.setCouponRate(nf.format(instrument.getCouponRate()) + "%");
			}
			dto.setDayBasis(instrument.getDayBasis());
			dto.setId(instrument.getId());
			dto.setListedInsCode(instrument.getInstrumentCode());
			dto.setInstrumentCode(instrument.getInstrumentCode());
			dto.setValueDate(df.format(instrument.getIssueDate()));
			dto.setIssuer(instrument.getIssuer().getId());
			dto.setIssuerName(instrument.getIssuer().getCode());
			dto.setLabel(instrument.getLabel());
			dto.setMaturityDate(df.format(instrument.getMaturityDate()));
			dto.setMinDenominal(Integer.toString(instrument.getMinDenominal().intValue()));
		}
		return dto;
	}
}
